//Global variables
var map;							
var markers;
var eventsArray;
var eventsStore;

Ext.onReady(function() {					
	//Create map instance
	map = new OpenLayers.Map();
	
	//Create Layers
	var osmLayer = new OpenLayers.Layer.OSM("OSM");				//OSM layer
	markers = new OpenLayers.Layer.Markers("Markers");			//Markers layer

	//Add layers
    map.addLayers([osmLayer, markers]);
        
    //Create map panel
    var mapPanel = new GeoExt.MapPanel({
        title: "Karte",	
        region: "center",
        map: map,
        center: new OpenLayers.LonLat(13.261764, 53.556218)
    		.transform(
    			  new OpenLayers.Projection("EPSG:4326"), 		//Transform from WGS 1984
        		  map.getProjectionObject() 					//To 'Spherical Mercator Projection' (EPSG:900913)
       		),
        zoom: 10
    });
    
    //Header graphic
    var headerGraphic = new Ext.BoxComponent({
    	cls:"headerGraphic", autoEl: {tag: "img", src: "./img/headerGraphic.png"}		//CSS reference
    });
    
    //Create login panel
    var loginPanel = new Ext.FormPanel({
    	defaultType: "textfield",
		baseCls: "loginPanel",							//Set CSS reference
	    labelWidth: 80,
	    defaults: {width: 135},
	    items :[
	    	{
	         fieldLabel: "Nutzername",
	         id: "username",
	         allowBlank:true
	        },
	        {
	         fieldLabel: "Passwort",
	         id: "password",
	         inputType: "password"
	        },
	        {
	         xtype: "button",
	         cls: "loginPanelButton",					//Set CSS reference
	         text: "Login",
	         handler: function(){      	 
	        	 //Check login input data, alert in case of missing parameters and send login request
	        	 var noEmptyFieldExpression = /^[^"']+$/;
	        	 
				 if(noEmptyFieldExpression.test(Ext.get("username").getValue()) == true && noEmptyFieldExpression.test(Ext.get("password").getValue()) == true){
	        		 loginRequest();
	        	 }
	        	 else if(noEmptyFieldExpression.test(Ext.get("username").getValue()) == false && noEmptyFieldExpression.test(Ext.get("password").getValue()) ==true){
	        		 alert("Es wurde kein Nutzername angegeben. Bitte keine Anfuehrungszeichen verwenden!");
	        	 }
	        	 else if(noEmptyFieldExpression.test(Ext.get("password").getValue()) == true && noEmptyFieldExpression.test(Ext.get("username").getValue()) == false){
	        		 alert("Es wurde kein Passwort angegeben. Bitte keine Anfuehrungszeichen verwenden!");
	        	 }
	        	 else{
	        		 alert("Es wurde kein Nutzername / Passwort angegeben. Bitte keine Anfuehrungszeichen verwenden!");
	        	 }
	         }
	     	}]	     
    });
    
    //Validate date input (enddt can't be earlier than startdt)
    Ext.apply(Ext.form.VTypes, {
    	daterange : function(val, field) {
            var date = field.parseDate(val);

            if(!date){
                return false;
            }
            if (field.startDateField) {
                var start = Ext.getCmp(field.startDateField);
                if (!start.maxValue || (date.getTime() != start.maxValue.getTime())) {
                    start.setMaxValue(date);
                    start.validate();
                }
            }
            else if (field.endDateField) {
                var end = Ext.getCmp(field.endDateField);
                if (!end.minValue || (date.getTime() != end.minValue.getTime())) {
                    end.setMinValue(date);
                    end.validate();
                }
            }
    	}
    });
        
    //Get event categories from MySQL-DB  and store them
    var allocatedEventCategoriesStore = new Ext.data.XmlStore({
    	autoLoad: true,
	    url: "./php/phpsql_getAllocatedEventCategories.php",
	    fields: ["name"],
	    record: "category"
	});
    
    
    var osLengthStore = new Ext.data.SimpleStore({								//Create store for the orbiting search in the filter panel   
        fields: ['value'],
        data: [[5],[10],[15],[20],[25],[30],[35],[40],[45],[50]],				//Set distance options
        autoLoad: true
    });

	var allocatedEventTownsPLZStore = new Ext.data.XmlStore({					//Get event towns from MySQL-DB and store them
    	autoLoad: true,
	    url: "./php/phpsql_getAllocatedEventTownsPLZ.php",
	    fields: ["name"],
	    record: "town"
	});
	
	var filterPanel = new Ext.FormPanel({										//Create panel for the filters
		frame: true,															//Disable frame
		cls: "filterPanel",														//Set the CSS reference name	
		items: [
		        	{
						layout: "column",						//Add filters to a column layout with 2 columns 
						items: [
						        	{ 											//Column #1
								        columnWidth: .50,						//Width of the columns = 50%
								        autoScroll:true,										
										layout: "form",
										labelWidth: 80,							//Set basic width for the labels								
										defaults: {width: 180},					//Set basic width of the labels
										items: [
										        	{
										        		xtype: "datefield",	
										        		format: "Y-m-d",		//Set date format
										        		fieldLabel: "Start",	//Set label	of the field					
										        		id: "startdt",			//Set id
										        		vtype: "daterange",		//Set reference for the function which validates the correct daterange
										        		endDateField: "enddt" 	//Set the id of the end date field
													},
													{
														xtype: "datefield",
														format: "Y-m-d",
														fieldLabel: "Ende",							
														id: "enddt",
														vtype: "daterange",
														startDateField: "startdt" 	//Set the id of the end date field
													},
													{
														xtype: "combo",
														mode: "local",				//Loads local data
														typeAhead: true,			//Allows to complete the results automatically when you type into the field
														triggerAction: "all",		//Allow all triggers
														fieldLabel: "Typ",			//Set label	of the field	
														id: "eventType",			//Set id
														displayField: "name",		//Set the displayed field of the combo box
														valueField: "name",			//Set the actual value field of the combo box
														store: allocatedEventCategoriesStore		//Set the store of the combo box
													},
													{
														xtype: "button",
														cls:"filterPanelButton",					//Set CSS reference name
														text: "Veranstaltungen suchen",				//Set label	of the button
														id:"filterPanelButton",
														/*
														 * 	Create handler for the button
														 *  If handler is triggered get all filter parameters and call getEvents function
														 */
														handler: function(){
															//Regular expression for filter elements
															var townEmptyExpression=/^$/;
															var townExpression=/(^(.)+, [0-9]{5}$)/;
															var eventTypeExpression=/(^$|^\w+$)/;
															var dateExpression=/(^$|^[0-9]{4}-(0[1-9]|1[0-2])-(0[1-9]|[1-2][0-9]|3[0-1])$)/;
															var eventRadiusExpression=/(^$|^[0-9]+$)/;
															if(dateExpression.test(Ext.get("startdt").getValue())==false){
																alert("Bitte Startdatum überprüfen!");
																}else{
																var startdt = Ext.get("startdt").getValue();
															}
																
															if(dateExpression.test(Ext.get("enddt").getValue())==false){
																alert("Bitte Enddatum überprüfen!");
																}else{
																var enddt = Ext.get("enddt").getValue();
															}
															
															if(eventRadiusExpression.test(Ext.get("osRadius").getValue())==false){
																alert("Bitte Radius überprüfen!");
																}else{
																var eventRadius = Ext.getCmp("osRadius").getValue();
															}
															
															if(dateExpression.test(Ext.get("startdt").getValue())==false){
																alert("Bitte Startdatum überprüfen!");
																}else{
																var startdt = Ext.get("startdt").getValue();
															}	
															
															if(townEmptyExpression.test(Ext.get("osCenter").getValue())==false){
																if(townExpression.test(Ext.get("osCenter").getValue())==false){
																	alert("Bitte vordefinierte Städte auswählen");			
																	}else{
																	var city=Ext.get("osCenter").getValue()																	
																	}		
															}
															
															if(eventTypeExpression.test(Ext.get("eventType").getValue())==false){
																	alert("Bitte Event Kategorie überprüfen!");			
																	}else{
																	var eventType = Ext.get("eventType").getValue();
															}	
															
															getEvents(startdt, enddt, eventType, eventRadius, city);																													
														}
													}
										] //Close items for first column
						        	},
									{
						        		columnWidth: .50,
						        		labelWidth: 80,							//Set basic width for the labels								
										defaults: {width: 180},					//Set basic width of the labels
						        		autoScroll:true,
										
						        		layout: "form",
						        		items: [
						        		        	{
														xtype: "combo",
														mode: "local",								//Loads local data						
														triggerAction: "all",						//Allow all triggers
														id: "osCenter",								//Set id
														fieldLabel: "Ort",							//Set label	of the field
														displayField: "name",						//Set the displayed field of the combo box
														valueField: "name",							//Set the actual value field of the combo box
														store: allocatedEventTownsPLZStore			//Set the store of the combo box
													
						        		        	},
													{	
						        		        		xtype: "combo",								
						        		        		mode: "local",								//Loads local data		
						        		        		triggerAction: "all",						//Allow all triggers
						        		        		fieldLabel: "Radius",						//Set label	of the field
						        		        		id: "osRadius",								//Set id
						        		        		displayField: "value",						//Set the displayed field of the combo box
						        		        		valueField: "value",						//Set the actual value field of the combo box
						        		        		store: osLengthStore						//Set the store of the combo box
													}
										] //Close items for second column
									}
						]
		        	}
		]
	});
  
    
    
    //Create data store for the events 
    eventsStore = new Ext.data.ArrayStore({
        fields: [
           {name: "name"},
           {name: "description"},
           {name: "eventsCategory"},
           {name: "fee"},
           {name: "date"},
           {name: "street"},
           {name: "nr"},
           {name: "plz"},
           {name: "town"}
        ]
    });
    
    var eventsGrid = new Ext.grid.GridPanel({				//Create eventsGrid
    	store: eventsStore,									//Set the store of the grid
        viewConfig: {										//Set grid = 100% of the div-container
			forceFit: true
		},
		autoHeight: true,									//Allow multiple rows; Height is being calculated automatically 
		columns: [											//Define the columns of the grid
		            {
		            	id       :"eventsName",				//Set the id of the column
		                header   : "Name", 					//Set the column header text
		                width    : 100, 					//Set default width of the column
		                sortable : true, 					//Allow the column to be sortable
		                dataIndex: "name"					//Set the reference for the eventsStore 
		            },
		            {
		                id       :"eventsCategory",
		                header   : "Typ",
		                sortable : true, 
		                width    : 60,  
		                dataIndex: "eventsCategory"
		            },
		            {
		                id       :"eventsDate",
		                header   : "Datum/Uhrzeit",
		                sortable : true, 
		                width    : 115,  
		                dataIndex: "date"
		            },
		            {
		                id       :"eventsStreet",
		                header   : "Straße",
		                width    : 100,  
		                dataIndex: "street"
		            },
		            {
		                id       :"eventsNr",
		                header   : "Nr",
		                width    : 30,  
		                dataIndex: "nr"
		            },
		            {
		                id       : "eventsTown",
		                header   : "Ort",
		                width    : 100,  
		                dataIndex: "town"
		            },
		            {
			            id		 : "eventsDescription",
			            header	 : "Beschreibung",
			            width    : 75,  
			            /*
			             * The renderer generates an link to the eventDescription page and adds the the event attributes as GET-parameters
			             */
			            renderer: function (val, meta, record){
			            	var url = "./eventDescription.php?";									//Url to the eventDescription page
			            	
			            	//Set GET-parameters

			            	var name = "name="+record.data.name;	
			            	var eventsCategory = "&eventsCategory="+record.data.eventsCategory;
			            	var date = "&date="+record.data.date;
			            	var street = "&street="+record.data.street;
			            	var nr = "&nr="+record.data.nr;
			            	var town = "&town="+record.data.town;
			            	
			            	var getParameters = name+eventsCategory+date+street+nr+town;			//Combined GET-parameters
			            	return "<a href='"+url+getParameters+"' target='_blank'>LINK</a>";		//Create the link 
			            }
		            }            
        ]
    });

    
  	//Create UI
	var viewport = new Ext.Viewport({							//Generating the viewport
	  layout: "border",											//Choose the preexisting layout type "border"
	  items: [
	      //Header
		  {
			region: "north",
			baseCls: "headerRegion",							//Set CSS reference
			//Header graphic + login area
			items: [headerGraphic, loginPanel]					//Add headerGraphic + loginPanel
		  },
		  //Sidebar
		  {
			region: "west",
			title: "Filter",
			split: true,
			collapsible: true,
			collapseMode: "mini",
	        autoScroll: true,
			cls: "publicPanel",									//Set CSS reference
			items: [
			  //Filter
			  filterPanel,										//Add filterPanel
			  eventsGrid										//Add eventsGrid
			]
		  },
		  //MapPanel
		  mapPanel												//Add mapPanel
	  ]
	});
});

/*
 * Get events from MySQL-DB via AJAX request 
 * + Get attributes from the returnig XML 
 * + store informations in eventsArray 
 * + placeMarker on the map
 */
function getEvents(startdt, enddt, eventType, eventRadius,city){
	Ext.Ajax.request({																//Sending AJAX request
	  url: "./php/phpsql_getEvents.php",
	  method: "POST",          
      params: {																		//Parameters
    	  startdt: startdt,
    	  enddt: enddt,
    	  eventType: eventType,
    	  eventRadius: eventRadius,
		  city:city
      },
	  success: function(response){													//Success function
		  	markers.clearMarkers();													//Clear current makers from markers layers
		  	
		  	var xml = response.responseXML;											//Save resulting XML
		
		  	var events = xml.documentElement.getElementsByTagName("event");			//Get events from XML
		  	
		  	eventsArray = new Array();
		  		
		  	for (var i = 0; i < events.length; i++) {								//Get event attributes + store attributes in eventsArray
		  		if(events[i].getElementsByTagName("name")[0].firstChild == null){
					var name = "";
				}
				else{
					var name = events[i].getElementsByTagName("name")[0].firstChild.data;
				}
				if(events[i].getElementsByTagName("description")[0].firstChild == null){
					var description = "";
				}
				else{
					var description = events[i].getElementsByTagName("description")[0].firstChild.data;
				}
				if(events[i].getElementsByTagName("eventcategory")[0].firstChild == null){
					var eventcategory = "";
				}
				else{
					var eventcategory = events[i].getElementsByTagName("eventcategory")[0].firstChild.data;
				}
		  		if(events[i].getElementsByTagName("fee")[0].firstChild == null){
					var fee = "";
				}
				else{
					var fee = events[i].getElementsByTagName("fee")[0].firstChild.data;
				}
				if(events[i].getElementsByTagName("date")[0].firstChild == null){
					var date = "";
				}
				else{
					var date = events[i].getElementsByTagName("date")[0].firstChild.data;
				}
				if(events[i].getElementsByTagName("street")[0].firstChild == null){
					var street = "";
				}
				else{
					var street = events[i].getElementsByTagName("street")[0].firstChild.data;
				}
				if(events[i].getElementsByTagName("nr")[0].firstChild == null){
					var nr = "";
				}
				else{
					var nr = events[i].getElementsByTagName("nr")[0].firstChild.data;
				}
				if(events[i].getElementsByTagName("plz")[0].firstChild == null){
					var plz = "";
				}
				else{
					var plz = events[i].getElementsByTagName("plz")[0].firstChild.data;
				}
				if(events[i].getElementsByTagName("town")[0].firstChild == null){
					var town = "";
				}
				else{
					var town = events[i].getElementsByTagName("town")[0].firstChild.data;
				}
				if(events[i].getElementsByTagName("lat")[0].firstChild == null){
					var lat = "";
				}
				else{
					var lat = events[i].getElementsByTagName("lat")[0].firstChild.data;
				}
				if(events[i].getElementsByTagName("long")[0].firstChild == null){
					var long = "";
				}
				else{
					var long = events[i].getElementsByTagName("long")[0].firstChild.data;
				}
				
				var visibility = events[i].getElementsByTagName("visibility")[0].firstChild.data; 
				
		  		var html = "<h3>"+name+"</h3><br/>"+description+"<br/><br/>"+"<b>Eintritt: </b><br/>"+fee+"&euro;"+"<br/><br/><b>Adresse:</b><br/>"+street+" "+nr+"<br/>"+plz+" "+town;
		  		 
		  		eventsArray[i] = new Array();
				eventsArray[i][0] = name;
				eventsArray[i][1] = description;
				eventsArray[i][2] = eventcategory;
				eventsArray[i][3] = fee;
				eventsArray[i][4] = date;
				eventsArray[i][5] = street;
				eventsArray[i][6] = nr;
				eventsArray[i][7] = plz;
				eventsArray[i][8] = town;
				eventsArray[i][9] = lat;
				eventsArray[i][10] = long;
				eventsArray[i][11] = visibility;
				 
				placeMarker(lat, long, html, visibility);									//Call placeMarker function
		  	}
	      eventsStore.loadData(eventsArray);									//Manually load local data
      }
	});                                    
}
/*
 * This function places the marker to the map
 */
function placeMarker(lat, long, html, visibility){													
	var size = new OpenLayers.Size(21,25);
	if (visibility == 1){
		var icon = new OpenLayers.Icon("http://openlayers.org/api/img/marker-green.png", size);	
	}
	else{
		var icon = new OpenLayers.Icon("http://www.openlayers.org/dev/img/marker.png", size);	
	}	
	var location = new OpenLayers.LonLat(long, lat).transform(
			  	   new OpenLayers.Projection("EPSG:4326"), 		//Transform from WGS 1984
			  	   map.getProjectionObject() 					//To 'Spherical Mercator Projection' (EPSG:900913)
   	);
	var marker =  new OpenLayers.Marker(location, icon);		//Create new OpenLayers marker object
	addPopup(marker, location, html);							//Call addPopup function
	markers.addMarker(marker);									//Add the marker to the map
}

/*
 * This function adds a popup to the marker
 */
function addPopup(marker, location, html){
	var anchor = {													//Set zero point of the popup window 
		size: new OpenLayers.Size(0,0),
		offset: new OpenLayers.Pixel(0,0)	
	};
	
	marker.events.register("mousedown", marker, function(evt) { 	//Add mousedown listener			
		map.setCenter(location);									//Set mapcenter to marker location
	
		var popup = new OpenLayers.Popup.FramedCloud(				//Define Popup
			"event-info-popup",
            location, 
            null,
            html,
            anchor,
            true
	    );

		map.addPopup(popup);										//Add popup to the map
		OpenLayers.Event.stop(evt); 						
	});
}


function loginRequest(){
	Ext.Ajax.request({									//Sending AJAX request
	  url: "./php/phpsql_login.php",
	  method: "POST",
	  params: {											//Setting parameters of the POST variable
      	username: Ext.get("username").getValue(),
      	password: Ext.get("password").getValue()
      },
	  success: function(response) {						//Callback function
	  	var resonseText = response.responseText;		//Get user role from MySQL-DB
	  	if(resonseText != "false"){			
	  		location.reload();							//If true refresh page
	  	}
	  	else{
	  		alert("Der Login ist fehlgeschlagen!");		//Alert that the login has failed
	  	}
	  },
	});
}